package system

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"log"
	"strconv"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	"yundian/internel/pkg/dingo/result"
)

type Dingo struct {
	engine *gin.Engine
}

// 初始化
func New(path string) *Dingo {
	if path == "" {
		log.Fatal("配置文件路径不能为空")
	}
	dingo.InitConstViper("./configs/const.yaml") // 初始化常量配置
	dingo.InitViper(path)                        // 初始化配置
	d := &Dingo{engine: gin.New()}               // 初始化gin引擎
	return d
}

// 注册api路由地址
func (d *Dingo) Register(router dingo.IRouter) *Dingo {
	if global.Cfg.Server.Mode == gin.ReleaseMode {
		gin.SetMode(gin.ReleaseMode) // gin设置成发布模式
	}
	// 加载全局中间件
	//d.engine.Use(dingo.ZapLogger(), dingo.ZapRecovery(true), dingo.CorsHandler())
	d.engine.Use(dingo.ZapLogger(), dingo.ErrorHandler(), dingo.CorsHandler())

	//g := d.engine.Group("admin/v1") // 分组
	//apiRouters := alipayrouter.Init()
	//for _, f := range apiRouters {
	//	f(g)
	//}

	// 注册路由信息
	d.engine = router.Init(d.engine)

	d.engine.NoMethod(func(ctx *gin.Context) {
		result.Response(ctx)(result.CodeNoMethod.Msg(), result.CodeNoMethod, nil)(result.BadRequest) // 400
	})
	d.engine.NoRoute(func(ctx *gin.Context) {
		result.Response(ctx)(result.CodeNoRoute.Msg(), result.CodeNoRoute, nil)(result.NotFound) // 404
	})
	return d
}

// 初始化组件
func (d *Dingo) Ready(components ...dingo.Component) *Dingo {
	for _, component := range components {
		component.Step()
	}
	defer func() {
		_ = zap.L().Sync() // 退出前,刷新所有缓冲区的日志
	}()
	return d
}

// 定时任务
func (d *Dingo) Task(cron string, expr interface{}) *Dingo {
	var err error
	if f, ok := expr.(func()); ok {
		_, err = dingo.GetCronTask().AddFunc(cron, f)
	}
	if err != nil {
		log.Println(err)
	}
	return d
	//c := cron.New()
	//// 也可以秒级任务
	////c := cron.New(cron.WithSeconds()) // 创建定时任务 秒
	////   spec := "0 */1 * * * *" // 每一分钟 如果用到分钟, 秒要设置为0
	////spec := "* */1 * * * *"
	//fmt.Println(c)
	//spec := "*/1 * * * *"    // 每一分钟，
	//c.AddFunc(spec, func() {
	//	i++
	//	log.Println("cron running:", i)
	//	fmt.Println("cron running:",i)
	//})
	//c.Start()
}

// 运行
func (d *Dingo) Go() {
	dingo.GetCronTask().Start()                                  // 运动定时任务
	_ = d.engine.Run(":" + strconv.Itoa(global.Cfg.Server.Port)) // 启动服务
}
